package com.alibaba.wallstreet.uitls;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StringUtil extends StringUtils {

    private static Logger       logger   = LoggerFactory.getLogger(StringUtil.class);

    private static final String SQL_LIKE = "%";

    /**
     * 全角转成半角
     * 
     * @param input
     * @return
     */
    public static String fullWidthTohalfWidth(String input) {
        if (isEmpty(regularTrim(input))) return "";
        char c[] = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == '\u3000') {
                c[i] = ' ';
            } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
                c[i] = (char) (c[i] - 65248);
            }
        }
        return new String(c);
    }

    /**
     * 判断是否是数字
     * 
     * @param str
     * @return
     */
    public static boolean isDigit(String str) {
        String RegularExp = "\\d*";
        return str.matches(RegularExp);
    }

    /**
     * 把一个字符串的$变量都用数组的值依次替换
     * 
     * @param str
     * @param value
     * @return
     */
    public static String variableSubstitute(String str, String[] value) {
        String temp = str;
        if (StringUtil.isNotBlank(temp) && value != null) {
            for (int i = 0; i < value.length && value[i] != null; i++)
                temp = replaceOnce(temp, "$", value[i]);
        }
        return temp;
    }

    // 根据传入的源，查找值，数目n，获得第n个匹配的值的位置
    public static int indexOfSpecial(String source, String findStr, int num) {
        int begin = -1;
        if (num < 1 || source == null || findStr == null || source.length() <= 0 || findStr.length() <= 0) return -1;
        for (int i = 0; i < num; i++) {
            begin = source.indexOf(findStr, begin + 1);
            if (begin == -1) {
                return -1;
            }
        }
        return begin;
    }

    /**
     * findStr在源字符串出现的次数
     * 
     * @param source
     * @param findStr
     * @return
     */
    public static int getNumOfSpecial(String source, String findStr) {
        int ret = 0;
        int i = 1;
        while (indexOfSpecial(source, findStr, i) != -1) {
            i++;
            ret++;
        }
        return ret;
    }

    /**
     * 字符串是否为空
     * 
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        if (str == null) return true;
        if (str.length() == 0) return true;
        return false;
    }

    /**
     * 对象是否为空
     * 
     * @param obj
     * @return
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null) return true;
        else if (obj instanceof String) return isEmpty((String) obj);
        else if (obj instanceof BigDecimal) {
            if (BigDecimal.valueOf(0).equals(obj)) return true;
        } else if (obj instanceof Integer) {
            if (Integer.valueOf(0).equals(obj)) return true;
        } else if (obj instanceof Double) {
            if (Double.valueOf(0).equals(obj)) return true;
        }
        return false;
    }

    /**
     * 截取定长字符串
     * 
     * @param source
     * @param length
     * @return
     * @see com.alibaba.wallstreet.uitls.StringUtil.limitByByte(String, int)
     */
    @Deprecated
    public static String truncStrByLen(String source, int length) {
        String ret = "";
        int truncLen = length;
        if (truncLen < 0) truncLen = 0;
        if (truncLen % 2 != 0) truncLen = truncLen - 1;
        if (source != null) {
            byte[] tmpStr = new byte[truncLen];
            if (source.getBytes().length <= truncLen) return source;
            System.arraycopy(source.getBytes(), 0, tmpStr, 0, truncLen);
            ret = new String(tmpStr).trim();
        }
        return ret;
    }

    /**
     * 截取字符串开头指定长度（字节）的子字符串
     * 
     * @param src
     * @param byteLen
     * @return
     */
    public static String limitByByte(String src, int byteLen) {
        if (byteLen <= 0) {
            throw new RuntimeException("invalid limit.");
        }
        String cs = Charset.defaultCharset().displayName();
        if ("UTF-8".equals(cs)) {
            if (byteLen % 3 == 1) {
                byteLen += 2;
            } else if (byteLen % 3 == 2) {
                byteLen += 1;
            }
        } else if ("GBK".equals(cs)) {
            if (byteLen % 2 != 0) {
                byteLen += 1;
            }
        }

        String ret = "";
        try {
            if (src != null) {
                byte[] tmpStr = new byte[byteLen];
                if (src.getBytes(cs).length <= byteLen) {
                    return src;
                }
                System.arraycopy(src.getBytes(cs), 0, tmpStr, 0, byteLen);
                ret = new String(tmpStr, cs).trim();
            }
        } catch (Exception e) {
            throw new RuntimeException("invalid charset.");
        }
        return ret;
    }

    /**
     * 截取字符串开头指定长度（字符）的子字符串
     * 
     * @param src
     * @param len
     * @return
     */
    public static String limit(String src, int len) {
        if (len <= 0) {
            throw new RuntimeException("invalid limit.");
        }
        if (src == null) {
            throw new RuntimeException("invalid source string.");
        }
        if (len > src.length()) {
            return src;
        } else {
            return src.substring(0, len);
        }

    }

    /**
     * @param source
     * @param special
     * @param num
     * @return
     */
    // //根据传入的源，查找值#，数目n，获得第n个被查找值例如#包含的值
    public static String subStringBySpecial(String source, String special, int num) {
        if (num < 1 || source == null || special == null || source.length() <= 0 || special.length() <= 0) return null;
        int beginNum = indexOfSpecial(source, special, num);
        int endNum = indexOfSpecial(source, special, num + 1);
        if (beginNum < 0 || endNum < 0) return null;
        String ret = source.substring(beginNum + 1, endNum);
        return ret;
    }

    public static String subStringBySpecial_B_E(String source, String special, int num) {
        if (num < 1 || source == null || special == null || source.length() <= 0 || special.length() <= 0) return null;
        boolean isBegin = false;
        boolean isEnd = false;
        if (indexOfSpecial(source, special, 1) == 0) {
            isBegin = true;
        }
        if (source.lastIndexOf(special) == (source.length() - 1)) {
            isEnd = true;
        }

        if (num == 1 && !isBegin) {// 首位不为#
            if (indexOfSpecial(source, special, 1) >= 0) {
                return source.substring(0, indexOfSpecial(source, special, 1));
            } else {
                return null;
            }
        }
        if (!isBegin) num--;
        int beginNum = indexOfSpecial(source, special, num);
        int endNum = indexOfSpecial(source, special, num + 1);
        if (beginNum < 0 || (endNum < 0 && isEnd)) // 查不到
        return null;
        if (beginNum > 0 && endNum < 0 && !isEnd) {
            return source.substring(beginNum + 1);
        }

        return source.substring(beginNum + 1, endNum);
    }

    public static String regularTrim(String str) {
        if (str != null) {
            String RegularExp = "^[　 ]+|[　 ]+$";
            String returnStr = str.replaceAll(RegularExp, "");
            return returnStr;
        } else {
            return null;
        }
    }

    public static void testRegularTrim(String[] args) {
        String str_qj = "　  团体              　　　　";
        String str_bj = " dd  　";
        regularTrim(str_qj);
        regularTrim(str_bj);
        regularTrim("");
        regularTrim(null);
    }

    public static String toString(Object obj) {
        return ReflectionToStringBuilder.toString(obj);
    }

    // public static void main(String[] args) {
    // String abc = "!@#$%^&*";
    // System.out.println(regularTrim(abc));
    // }

    public static String getSQLLikeCriteria(String fieldValeLike) {
        String value = StringUtils.trimToNull(fieldValeLike);
        if (value == null) {
            throw new RuntimeException("The fieldValeLike is invalid");
        }
        return new StringBuilder(SQL_LIKE).append(value).append(SQL_LIKE).toString();
    }

    /**
     * 将xml中的特殊字符转义 &---->&amp; '---->&apos; <---->&lt; >---->&gt; "---->&quot;
     * 
     * @param value
     * @return
     */
    public static String getStrReplaceSpecialChars(String value) {
        if (StringUtils.isBlank(value)) {
            return value;
        }
        value = value.replaceAll("&", "&amp;");
        value = value.replaceAll("'", "&apos;");
        value = value.replaceAll("<", "&lt;");
        value = value.replaceAll(">", ">&gt;");
        value = value.replaceAll("\"", "&quot;");
        return value;
    }

    /**
     * 读文件将文件转成String(此代码慎用，因为如果文件太大，直接加载到内存会导致内存溢出) 此方法目前用在HSBC的读ACK文件处，因为当有中文的时候ACK中有乱码
     * 我们的处理方式是将乱码替换掉，因为乱码的部分是收款账号的收款地址或者账户名，不影响业务
     * 
     * @param src
     * @return
     */
    public static String readFromFile(File src) {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(src), "utf-8"));
            StringBuilder stringBuilder = new StringBuilder();
            String content;
            while ((content = bufferedReader.readLine()) != null) {
                stringBuilder.append(content);
            }
            return stringBuilder.toString();
        } catch (FileNotFoundException e) {
            return null;
        } catch (IOException e) {
            return null;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    logger.error("Close IO err", e);
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(readFromFile(new File(
                                                 "D:\\alibaba\\CS\\com.dlj.cs\\src\\main\\java\\hsbc\\ACKSTD2.CJ071.111122370999.PGP.xml")));
    }

    /**
     * 全角转半角
     * 
     * @param key
     * @return
     */
    public static String toDBC(String input) {

        char c[] = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == '\u3000') {
                c[i] = ' ';
            } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
                c[i] = (char) (c[i] - 65248);

            }
        }
        return new String(c);
    }

    /**
     * 测试用的 public static void main(String[] args) { String a = "中国"; System.out.println(getStrReplaceSpecialChars(a));
     * System.out.println(getStrReplaceSpecialChars2(a)); String a2 = "中&国&化'me&you&<h>y\"";
     * System.out.println(getStrReplaceSpecialChars(a2)); System.out.println(getStrReplaceSpecialChars2(a2)); }
     **/
}
